package com.example.connection;

import android.app.Fragment;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.AdvertiseCallback;
import android.bluetooth.le.AdvertiseData;
import android.bluetooth.le.AdvertiseSettings;
import android.bluetooth.le.BluetoothLeAdvertiser;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.ViewGroup;

import com.example.connection.ui.connection.ConnFragment;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.navigation.NavigationView;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.lifecycle.MutableLiveData;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import androidx.drawerlayout.widget.DrawerLayout;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;

import com.example.connection.databinding.ActivityMainBinding;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private AppBarConfiguration mAppBarConfiguration;
    private ActivityMainBinding binding;
    private static final int REQUEST_ENABLE_BT = 2;
    private boolean mScanning;
    private Handler handler;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;
    BluetoothAdapter bluetoothAdapter;
    Fragment connFragment;
    Boolean b = false;
    List<BluetoothDevice> MyDeviceList = new ArrayList<BluetoothDevice>();
    public MutableLiveData<List> BTDeviceListData;
    public MutableLiveData<String> notifyLiveData;
    private final static String TAG = "mytag";

    private BluetoothManager bluetoothManager;
    private String bluetoothDeviceAddress;
    private BluetoothGatt bluetoothGatt;
    private int connectionState = STATE_DISCONNECTED;

    private static final int STATE_DISCONNECTED = 0;
    private static final int STATE_CONNECTING = 1;
    private static final int STATE_CONNECTED = 2;

    public final static String ACTION_GATT_CONNECTED =
            "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
    public final static String ACTION_GATT_DISCONNECTED =
            "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
    public final static String ACTION_GATT_SERVICES_DISCOVERED =
            "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
    public final static String ACTION_DATA_AVAILABLE =
            "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
    public final static String EXTRA_DATA =
            "com.example.bluetooth.le.EXTRA_DATA";
    BluetoothGattCharacteristic BCFFF1;
    BluetoothGattCharacteristic BCFFF2,BCFFF3;
    public Boolean isMaster = true;
    //public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString("fff1");

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        BTDeviceListData = new MutableLiveData<>();
        notifyLiveData = new MutableLiveData<>();
        binding = ActivityMainBinding.inflate(getLayoutInflater());
        handler = new Handler();
        bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
        setContentView(binding.getRoot());
        setSupportActionBar(binding.appBarMain.toolbar);
//        binding.appBarMain.fab.setOnClickListener(new View.OnClickListener() {
//            @Override
//            public void onClick(View view) {
//                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
//                        .setAction("Action", null).show();
//            }
//        });
        DrawerLayout drawer = binding.drawerLayout;
        NavigationView navigationView = binding.navView;
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        mAppBarConfiguration = new AppBarConfiguration.Builder(
                R.id.nav_home, R.id.nav_gallery, R.id.nav_slideshow, R.id.nav_chat, R.id.nav_conn)
                .setOpenableLayout(drawer)
                .build();
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        NavigationUI.setupActionBarWithNavController(this, navController, mAppBarConfiguration);
        NavigationUI.setupWithNavController(navigationView, navController);

        // Get the default adapter（获取默认适配器）
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        //判断设备是否有蓝牙
        if (bluetoothAdapter == null) {
            // Device doesn't support Bluetooth(设备不支持蓝牙)
            Log.i("mytag", "Device doesn't support Bluetooth");
        }
        //检查是否启用了蓝牙（isEnabled)，没有则申请启用蓝牙
        if (!bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
        //集合类（容器），获取已配对设备
        Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();

        if (pairedDevices.size() > 0) {
            // There are paired devices. Get the name and address of each paired device.（获取名称和mac)
            for (BluetoothDevice device : pairedDevices) {
                String deviceName = device.getName();
                String deviceHardwareAddress = device.getAddress(); // MAC address
                Log.i("mytag", "name1:" + deviceName);
                Log.i("mytag", "deviceHardwareAddress1:" + deviceHardwareAddress);
                //添加到list数组
                //  MyDeviceList.add(device);
            }
        }
        // Register for broadcasts when a device is discovered.(发现设备，注册广播）
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(receiver, filter);
        //connFragment = getFragmentManager().findFragmentById(R.id.nav_conn);

    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    //停止扫描
                    mScanning = false;
                    bluetoothAdapter.stopLeScan(leScanCallback);
                }
            }, SCAN_PERIOD);
            //开始扫描
            mScanning = true;
            bluetoothAdapter.startLeScan(leScanCallback);
        } else {
            //停止扫描
            mScanning = false;
            bluetoothAdapter.stopLeScan(leScanCallback);
        }
    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback leScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
//                            leDeviceListAdapter.addDevice(device);
//                            leDeviceListAdapter.notifyDataSetChanged();
                            //将device添加到list
                            //将MyDeviceList遍历赋值给device1
                            for (BluetoothDevice device1 : MyDeviceList) {
                                //如果My
                                if (device1.getAddress().equals(device.getAddress())) {
                                    b = true;
                                    break;
                                }
                            }
                            if (device.getName() != null & !b) {
                                MyDeviceList.add(device);
                            }
                            //设置list给data
                            BTDeviceListData.setValue(MyDeviceList);

                        }
                    });
                }
            };

    //开始扫描蓝牙设备，返回Boolean值
    public void onScanButtonClicked(View view) {
        //  boolean aa = bluetoothAdapter.startDiscovery();
        // Log.i("mytag", "已点击" + aa);
        scanLeDevice(true);
    }
    public void setF1Notify(Boolean b){
        Boolean aa1=
                bluetoothGatt.setCharacteristicNotification(BCFFF1, b);
        Log.i(TAG,"boolean是"+aa1);
        if(aa1) {
            List<BluetoothGattDescriptor> descriptorList = BCFFF1.getDescriptors();
            if(descriptorList != null && descriptorList.size() > 0) {
                for(BluetoothGattDescriptor descriptor : descriptorList) {
                    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
                    bluetoothGatt.writeDescriptor(descriptor);
                }
            }
        }

    }
    //根据index连接ble设备，回调方法是BluetoothGattCallback
    public void connectDeviceWithIndex(int index) {
        BluetoothDevice device = MyDeviceList.get(index);
        BluetoothGatt bluetoothGatt = device.connectGatt(this, false, gattCallback);
    }

    // Various callback methods defined by the BLE API.
    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            String intentAction;
            //已连接
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                intentAction = ACTION_GATT_CONNECTED;
                connectionState = STATE_CONNECTED;
                //    broadcastUpdate(intentAction);
                Log.i(TAG, "Connected to GATT server.");
                //开始扫描service服务,回调方法是onServicesDiscovered
                bluetoothGatt=gatt;
                Boolean bb  = bluetoothGatt.discoverServices();
                Log.i(TAG, "Attempting to start service discovery:"+bb );

            } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                //已断开
                intentAction = ACTION_GATT_DISCONNECTED;
                connectionState = STATE_DISCONNECTED;
                Log.i(TAG, "Disconnected from GATT server.");
                //   broadcastUpdate(intentAction);
            }
        }

        @Override
        // New services discovered（新服务被发现）
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                // broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                Log.i(TAG,"gatt是:"+gatt.getServices());
                for (BluetoothGattService service :gatt.getServices()){
                    Log.i(TAG,"service:"+service.getUuid().toString());
                    if (service.getUuid().toString().contains("fff0")){
                        for (BluetoothGattCharacteristic BC:service.getCharacteristics()){
                            Log.i(TAG,"BC是："+BC.getUuid().toString());
                            if (BC.getUuid().toString().contains("fff1")){
                                //fff1 是读和通知属性，从这个地方收从机发过来的信息
                                BCFFF1=BC;
                            }
                            if (BC.getUuid().toString().contains("fff2")){
                                //fff2 是写属性，给从机发信息
                                BCFFF2 =BC;
                            }
                            if (BC.getUuid().toString().contains("fff3")){
                                //fff3 是读，写，通知
                                BCFFF3=BC;
                            }
                        }
                    }
                }
            } else {
                Log.w(TAG, "onServicesDiscovered received: " + status);
            }
        }

        @Override
// Characteristic notification
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
           Log.i(TAG,"收到的通知："+characteristic.getStringValue(0));
           notifyLiveData.postValue(characteristic.getStringValue(0));
        }
        @Override
        // Result of a characteristic read operation
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                //  broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
            }
        }
    };
    public void sendMSG(String msg){
        BCFFF2.setValue(msg.getBytes(StandardCharsets.UTF_8));
        bluetoothGatt.writeCharacteristic(BCFFF2);

    }
     private void setServer(){

        BluetoothGattServer bluetoothGattServer = bluetoothManager.openGattServer(this, new BluetoothGattServerCallback() {
            @Override
            public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
                super.onConnectionStateChange(device, status, newState);
                Log.i("tag","onConnectionStateChange:"+newState);
            }

            @Override
            public void onServiceAdded(int status, BluetoothGattService service) {
                super.onServiceAdded(status, service);
                Log.i("tag","onServiceAdded:"+status);
            }

            @Override
            public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
                super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
                Log.i("tag","onCharacteristicReadRequest:"+characteristic);
            }

            @Override
            public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
                Log.i("tag","onCharacteristicWriteRequest:"+characteristic);
            }

            @Override
            public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
                super.onDescriptorReadRequest(device, requestId, offset, descriptor);
                Log.i("tag","onDescriptorReadRequest:"+descriptor);
            }

            @Override
            public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
                super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);
                Log.i("tag","onDescriptorWriteRequest:"+descriptor);
            }

            @Override
            public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
                super.onExecuteWrite(device, requestId, execute);
                Log.i("tag","onExecuteWrite:"+requestId);
            }

            @Override
            public void onNotificationSent(BluetoothDevice device, int status) {
                super.onNotificationSent(device, status);
                Log.i("tag","onNotificationSent:"+status);
            }

            @Override
            public void onMtuChanged(BluetoothDevice device, int mtu) {
                super.onMtuChanged(device, mtu);
                Log.i("tag","onMtuChanged:"+mtu);
            }

            @Override
            public void onPhyUpdate(BluetoothDevice device, int txPhy, int rxPhy, int status) {
                super.onPhyUpdate(device, txPhy, rxPhy, status);
                Log.i("tag","onPhyUpdate:"+status);
            }

            @Override
            public void onPhyRead(BluetoothDevice device, int txPhy, int rxPhy, int status) {
                super.onPhyRead(device, txPhy, rxPhy, status);
                Log.i("tag","onPhyRead:"+status);
            }
        });
         BluetoothGattService service = new BluetoothGattService(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb"), 0);
         BluetoothGattCharacteristic characteristic1 = new BluetoothGattCharacteristic(UUID.fromString("0000fff1-0000-1000-8000-00805f9b34fb"), BluetoothGattCharacteristic.PROPERTY_READ | BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_READ);
         BluetoothGattDescriptor descriptor1 = new BluetoothGattDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);
         BluetoothGattDescriptor descriptor11 = new BluetoothGattDescriptor(UUID.fromString("00002901-0000-1000-8000-00805f9b34fb"),BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);

         BluetoothGattCharacteristic characteristic2 = new BluetoothGattCharacteristic(UUID.fromString("0000fff2-0000-1000-8000-00805f9b34fb"), BluetoothGattCharacteristic.PROPERTY_WRITE, BluetoothGattCharacteristic.PERMISSION_WRITE);
         BluetoothGattDescriptor descriptor2 = new BluetoothGattDescriptor(UUID.fromString("00002901-0000-1000-8000-00805f9b34fb"),BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);

         BluetoothGattCharacteristic characteristic3 = new BluetoothGattCharacteristic(UUID.fromString("0000fff3-0000-1000-8000-00805f9b34fb"), BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PROPERTY_WRITE| BluetoothGattCharacteristic.PROPERTY_NOTIFY, BluetoothGattCharacteristic.PERMISSION_WRITE);
         BluetoothGattDescriptor descriptor3 = new BluetoothGattDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"),BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);
         BluetoothGattDescriptor descriptor31 = new BluetoothGattDescriptor(UUID.fromString("00002901-0000-1000-8000-00805f9b34fb"),BluetoothGattDescriptor.PERMISSION_WRITE | BluetoothGattDescriptor.PERMISSION_READ);

         characteristic1.addDescriptor(descriptor1);
         characteristic1.addDescriptor(descriptor11);
         service.addCharacteristic(characteristic1);

         characteristic2.addDescriptor(descriptor2);
         service.addCharacteristic(characteristic2);

         characteristic3.addDescriptor(descriptor3);
         characteristic3.addDescriptor(descriptor31);
         service.addCharacteristic(characteristic3);

         bluetoothGattServer.addService(service);


     }
    /**
     * Begin advertising over Bluetooth that this device is connectable
     * and supports the Current Time Service.
     */
    BluetoothLeAdvertiser mBluetoothLeAdvertiser;
    public void startAdvertising() {
        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
        mBluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
        if (mBluetoothLeAdvertiser == null) {
            Log.w(TAG, "Failed to create advertiser");
            return;
        }

        AdvertiseSettings settings = new AdvertiseSettings.Builder()
                .setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED)
                .setConnectable(true)
                .setTimeout(0)
                .setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_MEDIUM)
                .build();

        AdvertiseData data = new AdvertiseData.Builder()
                .setIncludeDeviceName(true)
                .setIncludeTxPowerLevel(false)
                .addServiceUuid(new ParcelUuid(UUID.fromString("0000fff0-0000-1000-8000-00805f9b34fb")))
                .build();

        mBluetoothLeAdvertiser.startAdvertising(settings, data, mAdvertiseCallback);
        setServer();
    }
    AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
        @Override
        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
            super.onStartSuccess(settingsInEffect);
            Log.i("mytag","settingsInEffect是："+settingsInEffect.toString());
        }

        @Override
        public void onStartFailure(int errorCode) {
            super.onStartFailure(errorCode);
            Log.i("mytag","errorCode是："+errorCode);

        }
    };
    /**
     * Stop Bluetooth advertisements.
     */
    private void stopAdvertising() {
        if (mBluetoothLeAdvertiser == null) return;

        mBluetoothLeAdvertiser.stopAdvertising(mAdvertiseCallback);
    }
    // Create a BroadcastReceiver for ACTION_FOUND.（为A_D注册广播接收器）
    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            //Log.i("mytag","已点击1");
            //判断扫描结果和本地蓝牙是否相同
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                // Discovery has found a device. Get the BluetoothDevice
                // object and its info from the Intent.
                //添加不相同的设备到BluetoothDevice
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String deviceName = device.getName();
                String deviceHardwareAddress = device.getAddress(); // MAC address
                Log.i("mytag", "name:" + deviceName);
                Log.i("mytag", "deviceHardwareAddress:" + deviceHardwareAddress);
                //将device添加到list
                MyDeviceList.add(device);
                //设置list给data
                BTDeviceListData.setValue(MyDeviceList);
            }
        }
    };

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // Don't forget to unregister the ACTION_FOUND receiver.(注销广播）
        unregisterReceiver(receiver);
    }

    //蓝牙状态回传
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        Log.i("mytag", "requestCode：" + requestCode);
        Log.i("mytag", "resultCode：" + resultCode);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onSupportNavigateUp() {
        NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
        return NavigationUI.navigateUp(navController, mAppBarConfiguration)
                || super.onSupportNavigateUp();
    }
}